package webserver;

import java.io.*;
import java.net.*;
import java.util.logging.Logger;

/**
 * maneja una conexi�n.
 * 
 * @author lucas
 */
public class Client extends Thread {

    /**
     * Constructor
     */
    public Client(Socket socket) {
        log.info("Se instancia nuevo cliente");
        this.setUncaughtExceptionHandler(new UncaughtExceptionHandler()
        {
            @Override
            public void uncaughtException(Thread t, Throwable ex) {
                log.severe(ex.getMessage());
                log.severe("ThreadException" + this.getClass().toString() + ", Name " + t.getName());
                System.exit(1);
            }
        });
        this.socket = socket;
        try {
            inFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            outToClient = new DataOutputStream(socket.getOutputStream());
        } catch (Exception ex) {
            return;
        }
        this.start();
    }
    
    @Override
    public void run() {
        try {
            while (true) {
                String data = getRequest();
                sendResp(generateResp());
            }
        } catch (Exception ex) {
            log.info("cliente terminado");
            log.info(util.stack2String(ex));
        } finally {
            kill();
        }
    }

    /**
     * mata el thread
     */
    public void kill() {
        try {
            socket.close();
        } catch (Exception ex) {
            log.info(ex.getMessage());
        }
    }

    /**
     * genera rta aleatoria
     * 
     * @return 
     */
    private String generateResp() {
//        voltage_mod += (voltage_mod%2 > 0 ? 1:-1);
        voltage_ang += 0.25;
//        current_mod += (voltage_mod%2 > 0 ? 1:-1);
        current_ang -= 0.10;
        return String.format("resp=[get_last_measure]\nvoltage_mod=[%f]\nvoltage_ang=[%f]\ncurrent_mod=[%f]\ncurrent_ang=[%f]\n", voltage_mod, voltage_ang, current_mod, current_ang);
    }

    private double voltage_mod = 8;
    private double voltage_ang = 8;
    private double current_mod = 8;
    private double current_ang = 8;
    
    
    /**
     * recibe el request y lo devuelve digerido
     * 
     * @return 
     */
    private String getRequest() throws Exception {
        String currentLine;
        String buffer = new String();   
        int content = 0;
        while ( (currentLine = inFromClient.readLine()) != null && currentLine.length() > 0 ) {
            buffer += currentLine + "\n";
            if (currentLine.contains("Content-Length:")) {
                String tokens[] = currentLine.split(":");
                content = Integer.valueOf(tokens[1].trim()).intValue();
            }
        }   
        headerRequest = new String(buffer);
        String data = new String();
        int character;
        while (data.length() < content && (character = inFromClient.read()) > 0) {
            data += String.valueOf((char) character);
        }
        log.info("RX |" + headerRequest + "\n" + data + "|");
        return data;
    }

    /**
     * envia respuesta
     * 
     * @param resp
     * @throws Exception 
     */
    private void sendResp(final String data) throws Exception {
        String response = new String();
        response += "HTTP/1.1 200 OK" + "\r\n";
        response += "Server: FREE-RTOS" + "\r\n";
        response += "Access-Control-Allow-Origin: *" + "\r\n";
        response += "Content-Type: text/html; charset=UTF-8" + "\r\n";
        response += "Content-Language: en-us" + "\r\n";
        response += "Content-Length: ";
        response += String.format("%d", data.length()) + "\r\n";
        response += "Connection: keep-alive" + "\r\n";
//        response += "Connection: close" + "\r\n";
        
        response += "\r\n";
        response += data;
        log.info("TX |" + response + "|");

//        RESPUESTA CON DELAYS
//        this.sleep(5000);
//        outToClient.writeBytes(response.substring(0, response.length() - 10));
//        this.sleep(5000);
//        outToClient.writeBytes(response.substring(response.length() - 10, response.length()));

        outToClient.writeBytes(response);
        outToClient.flush();
    }
    
    /***************************************************************************
     * Variables privadas
     */
    private Logger log = Logger.getAnonymousLogger();
    private Socket socket = null;
    private BufferedReader inFromClient = null;
    private DataOutputStream outToClient = null;
    private String headerRequest = null;
}
